package com.main;

import java.awt.Font;

import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.vector.Vector3f;
import org.newdawn.slick.Color;
import org.newdawn.slick.TrueTypeFont;

import com.engine.Engine;
import com.engine.I2DRenderer;
import com.engine.I3DRenderer;
import com.engine.RenderMode;
import com.engine.TextureAtlas;
import com.world.ChunkRenderer;

import static org.lwjgl.opengl.GL11.*;

public class Main {

	public static void main(String[] args) {

		Engine e = new Engine(800, 480, RenderMode.RENDER_MIXED) {

			@Override
			public void initialize() {
				glMatrixMode(GL_PROJECTION);
				glLoadIdentity();
				// here was the problem: perspective was made on 2d drawing -
				// EPIC fail
				GLU.gluPerspective((float) 30, (float) this.width
						/ (float) this.height, 0.001f, 1000f);
				glMatrixMode(GL_MODELVIEW);
				//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
				glEnable(GL_TEXTURE_2D);
				glColor3f(1.0f, 1.0f, 1.0f);
				glEnable(GL_CULL_FACE);
				glCullFace(GL_BACK);
				glEnable(GL_DEPTH_TEST);
				
				//GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);               
				GL11.glClearDepth(1);  
				GL11.glShadeModel(GL11.GL_SMOOTH); 
				GL11.glEnable(GL11.GL_BLEND);
				GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
				//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
				Mouse.setGrabbed(true);
			}

			@Override
			public void begin3D() {
				glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
				glEnable(GL_DEPTH_TEST);
				glMatrixMode(GL_PROJECTION);
				glLoadIdentity();
				GLU.gluPerspective((float) 30, (float) this.width
						/ (float) this.height, 0.001f, 1000f);
				glMatrixMode(GL_MODELVIEW);
				glLoadIdentity();
			}

			@Override
			public void begin2D() {
				glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
				glDisable(GL_DEPTH_TEST);
				glMatrixMode(GL_PROJECTION);
				glLoadIdentity();
				GL11.glOrtho(0, width, height, 0, 1, -1);
				glMatrixMode(GL_MODELVIEW);
				glLoadIdentity();
			}

		};
		I3DRenderer camera = new I3DRenderer() {
			Camera camera = new Camera(0, 0);
			float camRotSpeed = 0.1f;
			float camMoveSpeed = 0.1f;

			@Override
			public void render(int deltaTime) {
				int dx = Mouse.getDX();
				int dy = Mouse.getDY();
				camera.bearing(dx * deltaTime * camRotSpeed * 0.5f);
				camera.pitch(-dy * deltaTime * camRotSpeed * 0.5f);
				if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
					camera.move(+deltaTime * camMoveSpeed);
				}
				if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
					camera.move(-deltaTime * camMoveSpeed);
				}
				if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
					camera.strafe(-deltaTime * camMoveSpeed);
				}
				if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
					camera.strafe(+deltaTime * camMoveSpeed);
				}
				if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
					camera.setPosition(new Vector3f(camera.getPosition().x,
							camera.getPosition().y += deltaTime * camMoveSpeed,
							camera.getPosition().z));
				}
				if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
					camera.setPosition(new Vector3f(camera.getPosition().x,
							camera.getPosition().y -= deltaTime * camMoveSpeed,
							camera.getPosition().z));
				}
				camera.reorient();
				GL11.glMultMatrix(camera.getViewMatrixBuffer());
				GL11.glTranslatef(-camera.getPosition().x,
						-camera.getPosition().y, camera.getPosition().z);
			}

		};
		I3DRenderer axis = new I3DRenderer() {

			@Override
			public void render(int deltaTime) {
				glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
				glBegin(GL_LINES);
				{
					// x - red
					glColor4f(1.0f, 0.0f, 0.0f,0f);
					glVertex3f(0, 0, 0);
					glVertex3f(1000f, 0, 0);
					// y - blue
					glColor4f(0.0f, 0.0f, 1.0f,0f);
					glVertex3f(0, 0, 0);
					glVertex3f(0, 1000f, 0);
					// z - green
					glColor4f(0.0f, 1.0f, 0.0f,0f);
					glVertex3f(0, 0, 0);
					glVertex3f(0, 0, 1000f);
				}
				glEnd();
			}

		};

		e.addI3DRenderer(camera);
		e.addI3DRenderer(new ChunkRenderer(1, new TextureAtlas("resources/textures/terrainAtlas.png")));
		e.addI3DRenderer(axis);
		e.addI2DRenderer(new DebugInfoRenderer());
		e.enterLoop();
	}
}
class DebugInfoRenderer implements I2DRenderer
{
	private TrueTypeFont font;
	long frameCount = 0;
	long time = 0;
	String FPSText = "0";
	public DebugInfoRenderer()
	{
		Font awtFont = new Font("Times New Roman", Font.BOLD, 24);
		font = new TrueTypeFont(awtFont, true);
	}
	@Override
	public void render(int deltaTime) {
		frameCount++;
		time =  time + deltaTime;
		if(time >= 1000)
		{
			FPSText = String.valueOf(frameCount);
			frameCount=0;
			time = 0;
		}
		font.drawString(0,0, "FPS:"+FPSText, Color.blue);
	}
	
}